#!/bin/sh
#(c) Copyright Barry Kauler sept. 2011 bkhome.org
#2011 GPL licence v3 (/usr/share/doc/legal)
#the idea of this script is that it is called when PUPMODE==5 by scripts
#/usr/bin/wmreboot and /usr/bin/wmpoweroff (which are called via the Shutdown menu).
#X is still running.
#the normal shutdown sequence is:
# /usr/bin/wmpoweroff ->(return to) /usr/bin/xwin -> /sbin/poweroff -> /etc/rc.d/rc.shutdown
# /usr/bin/wmreboot ->(return to) /usr/bin/xwin -> /sbin/reboot -> /etc/rc.d/rc.shutdown
#this script is putting up some GUI dialogs while X is still running, so when
#rc.shutdown is reached, it won't have to put up text-mode dialogs.
#to avoid code duplication, get this to work with and without X, and also call this
#script from rc.shutdown. From the console, no X, type "poweroff" or "reboot" will
#also (conditionally) run this script, via rc.shutdown.
#110924 various tweaks. fix default partition highlight.
#111012 a pupdialog window had wrong text, needed different from non-X dialog.
#120327 only show "*RECOMMENDED*" partition for savefile if >256MB free.
#120327 expBOOTDRV needs to be exported to rc.shutdown.
#120427 01micko: support ext4 in save-file. 120428
#120512 Karl Godt: some parameters missing from lines 626, 630, 642.
#120514 Karl Godt: precaution, save-file must be bigger than size used in ram.
#130128 support udf f.s. (see also sfsget, puppyinstaller, pmount, pup_event_frontend_d, drive_all, probepart).
#130216 support f2fs.
#130221 the 240 sec timeout to shutdown without saving, actually aborts timeout. fixed. see also pupdialog, wmpoweroff, wmreboot.
#130525 extend duration of creating save file please wait window.
#130712 fix 130522, 130525 dlgs showing in tray.

export SHUTDOWNCONFIG=1

DEFAULT_SAVE_SIZE=512	#MB
TIMELIMIT=$(echo $TIMELIMIT | tr -dc '0-9')
[ "$TIMELIMIT" ] || TIMELIMIT=60

if [ ! $DISPLAY ];then
 export LANG=C #110928 console shutdown using 'dialog', disable i18n.
else
 export OUTPUT_CHARSET=UTF-8
fi

. gettext.sh # enables use of eval_gettext (several named variables) and ngettext (plurals)
export TEXTDOMAIN=shutdownconfig
T_title="$(gettext 'First shutdown: save session')" # used 8 times
T_nosave="$(gettext 'No suitable partitions to save to. Shutting down without saving.')"
T_continue="$(gettext 'Continue')"
T_abort="$(gettext 'Abort')"
T_no="$(gettext 'No')"
T_notsave="$(gettext 'DO NOT SAVE')"

#/etc/rc.d/rc.shutdown will call shutdownconfig if this file does not exist, then will read its contents...
echo -n "" > /tmp/shutdownconfig_results

. /etc/rc.d/PUPSTATE
. /etc/DISTRO_SPECS

if [ "$PUNIONFS" = "overlay" ];then
 echo "PUPMODE=21" > /tmp/shutdownconfig_results
 exit
fi

#puppy.sfs is in a subdirectory, default to saving in it...
PUPSFSFILE="`echo "$PUPSFS" | cut -f 3 -d ','`"
PSUBDIR="`dirname "$PUPSFSFILE"`"
[ "$PSUBDIR" = "/" ] && PSUBDIR=""
[ $PUPMODE -eq 5 ] && [ "$DEV1FS" = "iso9660" ] && PSUBDIR="" #100920 booting off cd, always default have savefile at /.
[ $PUPMODE -eq 5 ] && [ "$DEV1FS" = "udf" ] && PSUBDIR="" #130128 ditto, for udf f.s.
[ "$DEV1FS" = "msdos" ] && DEV1FS="vfat"

if [ $DISPLAY ];then
 export XDIALOG_HIGH_DIALOG_COMPAT=true #for Xdialog.
 DIALOGEXE="pupdialog"
 DIALOGEXE2="Xdialog"
 BACKGROUNDYELLOW='--background \#FFFF80' #110924 change to pale-yellow. yellow' #only works pupdialog.
 BACKGROUNDPINK='--background pink'     #ditto.
 BACKGROUNDORANGE='--background \#FFDC32' #110924 change to pale-orange. orange' #ditto.
 TITLEPARAM='--backtitle'
else
 DIALOGEXE="dialog"
 DIALOGEXE2="dialog"
 TITLEPARAM='--title'
 BACKGROUNDYELLOW=''
 BACKGROUNDPINK=''
 BACKGROUNDORANGE=''
fi

#120514 Karl Godt: precaution, save-file must be at least this big...
DU_INITRD_PUP_RW=0
[ "`mount | grep ' /initrd/pup_rw '`" != "" ] && DU_INITRD_PUP_RW=`du -B 1M -c /initrd/pup_rw |tail -n1 |awk '{print $1}'` #M=1024,MB=1000

#130525 introduced 130522. moved up.
ORANGEGTKRC="style \"windowstuff\"
{
    bg[NORMAL]      = \"#FFDC32\"
    fg[NORMAL]      = \"#000000\"
}
class \"*\" style \"windowstuff\"
"
echo "$ORANGEGTKRC" > /tmp/orange_gtkrc${$}

#================================================================

offerfido() {
 #offering non-root, ###PENDING### for now
 T_admin="$(gettext 'administrator')"
 T_fidomsg="`eval_gettext \"fido CURRENTLY EXPERIMENTAL STATUS, PLEASE CHOOSE \\\${T_admin}\"`"
 FIDOMSG2="\Zb\Z1${T_fidomsg}\Zn\ZB" #110926
 T_fidotitle="$(gettext 'First shutdown: ask fido')"
 T_yesno="$(eval_gettext "You are currently running Puppy as the \${T_admin} (also known as 'root') which is the preferred choice. However, for the paranoid, you may run Puppy as a less-privileged user 'fido'. Puppy boots up without requiring a password, whether as \${T_admin} or fido, but the latter will require jumping to \${T_admin} to perform some system-level tasks, which will require entry of the admin password -- this is viewed by many as an unnecessary hassle.")
$(eval_gettext "Puppy is structured in such a way that we consider running as \${T_admin} to be completely safe, and is the choice of most users, however fido is theoretically more secure.")
$(gettext "Note that Puppy only has one non-admin user, fido, as it is not a multi-user system in the normal sense -- instead, each person using Puppy on the same computer can have their own save-file (each one set to root or fido as the users wish).")

$(eval_gettext "Note also, the LoginManager (System menu) enables you to switch back to \${T_admin} if you decide later that you don't want to run as fido.")

${FIDOMSG2}"
 #offer to save non-root...
 ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_fidotitle" --colors --yes-label "$T_admin" --no-label "fido" --yesno "$T_yesno" 0 0 
 SAVECHOICE=$?
 [ $SAVECHOICE -eq 1 ] && /usr/sbin/root2user
}

choosepartfunc() {
 offerfido
 #dialog to choose what partition to create ${DISTRO_FILE_PREFIX}save.2fs on...
 case "$PMEDIA" in ""|cd|scsicd|satacd|idecd|atacd|usbcd) PCHOOSE="yes" ;; esac
 case "$DEV1FS" in ntfs|xxx) PCHOOSE="yes" ;; esac
 [ "$DEV1FS" = "msdos" ] && DEV1FS="vfat"

 expBOOTDRV=''
 if [ "$PMEDIA" = "usbflash" ];then #may have a small boot partition and a big 2nd.
  expBOOTDRV="/dev/`echo ${PDEV1} | sed -e 's%[0-9]*$%%'`"
  PCHOOSE="yes"
 fi
 if [ "$xPSUBDIR" -a "$PMEDIA" != "cd" ];then #if pup installed in a sub-directory, allow save-file in another partition (in same drive)...
  expBOOTDRV="/dev/`echo ${PDEV1} | sed -e 's%[0-9]*$%%'`"
  PCHOOSE="yes"
 fi
 if [ "$PSAVEMARK" != "" ];then #see /etc/rc.d/PUPSTATE
  devnameonly="`echo -n "$PDEV1" | sed -e 's/[0-9]*$//'`"
  SAVEPART="${devnameonly}${PSAVEMARK}" #partition that will-have ${DISTRO_FILE_PREFIX}save.
 fi
 if [ "$PSAVEPART" != "" ];then #see /etc/rc.d/PUPSTATE
  SAVEPART="${PSAVEPART}"
 fi
 if [ "$SAVEPART" != "" ];then
  spPATTERN='/dev/'"$SAVEPART"'|'
  SAVEFS="`probepart -m | grep "$spPATTERN" | cut -f 2 -d '|'`"
  SAVEFILE="$PSUBDIR/${DISTRO_FILE_PREFIX}save.2fs"
  PUPSAVE="$SAVEPART,$SAVEFS,$SAVEFILE"
  return 0
 fi
 if [ "$PCHOOSE" != "yes" ];then
  SAVEFS="$DEV1FS"
  SAVEPART="$PDEV1"
  SAVEFILE="$PSUBDIR/${DISTRO_FILE_PREFIX}save.2fs"
  PUPSAVE="$PDEV1,$DEV1FS,$SAVEFILE"
  return 0
 fi

 if [ "$expBOOTDRV" = "" ];then
  T_fidotitle="$(gettext 'First shutdown: get ready')"
  T_yesno1="$(eval_gettext "WARNING: If you want to create a save-file (\${DISTRO_FILE_PREFIX}save.2fs) in a NTFS partition (Windows XP), it is strongly recommended that you defragment the partition first.")
  $(eval_gettext 'Choose \Zb${T_abort}\ZB button to abort this save, start Windows and choose Start->All Programs->Accessories->System Tools->Defragment.')"
  T_yesno2="$(gettext 'Make sure any required USB, floppy, etc. is PLUGGED IN NOW!')"
  T_yesno3="$(eval_gettext 'Choose \Zb${T_continue}\ZB button to search available storage...')"
  T_yesno="\Z1${T_yesno1}\Zn\n\n\Z5${T_yesno2}\Zn\n\n${T_yesno3}" #111003
  case $DEV1FS in
  iso9660|udf)
   T_iso="`eval_gettext \"You have booted off a live-CD or DVD, and you can now save your personal settings and files to a USB Flash drive or any hard drive partition.
However, if you have burnt the CD/DVD as multisession (not closed), then sessions can be saved as additional tracks to the CD/DVD -- each saved session will appear on the CD/DVD as a directory with all the saved files in it, not as a single file. \Zb\Z1THIS IS STILL EXPERIMENTAL, AND DOES NOT WORK WITH LAPTOP OPTICAL DRIVES\Zn\ZB\"`"
    T_yesno="$T_iso\n\n$T_yesno
$(eval_gettext "or \Zb${T_cd}\ZB button to save your session back to the CD/DVD..." )"
    ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_fidotitle" --colors --extra-button --ok-label "$T_continue" --extra-label "$T_cd" --cancel-label "$T_abort" --yesno "$T_yesno" 0 0
   SAVECHOICE=$?
   [ "$SAVECHOICE" == "3" ] && PUPMODE=77 && SAVEPART="$PDEV1" && return 1 #save to cd/dvd.
   [ ! $SAVECHOICE -eq 0 ] && return 3 #skip. 
   ;;
  *)
   ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_fidotitle" --colors --yes-label "$T_continue" --no-label "$T_abort" --yesno "$T_yesno" 0 0
   SAVECHOICE=$?
   [ ! $SAVECHOICE -eq 0 ] && return 1 #abort.
   ;;
  esac
 fi

 #130216 add f2fs...
 PARTSLIST="`probepart -m 2> /dev/null | grep '^/dev/' | grep "$expBOOTDRV" | grep -E 'f2fs|ext2|ext3|ext4|reiserfs|btrfs|minix|msdos|vfat|exfat|ntfs' | cut -f 1-3 -d '|' | sed -e 's/msdos/vfat/g'`"

 #nothing to save to...
 if [ "$PARTSLIST" = "" ];then
  if [ $DISPLAY ];then
   /usr/lib/gtkdialog/box_splash -bg red -close box -fontsize large -timeout 10 -text "$T_nosave"
  else
   clear
   echo "T_nosave"
   sleep 5
  fi
  return 1
 fi
 T_waitprobing="$(gettext 'Please wait, probing partitions...')"
 if [ "$DISPLAY" ]; then
  /usr/lib/gtkdialog/box_splash -close never -fontsize large -text "$T_waitprobing" &
  ppPID=$!
 fi
 SCHOICES=""; DEFTAG=""
 rm -f /tmp/schoices.txt
 rm -f /tmp/shutdownconfig_deftag
 echo "$PARTSLIST" | grep -qw "$PDEV1" && INSTALLED="y" || INSTALLED=""
 echo "$PARTSLIST" |
 while read APART
 do
  ATAG="`echo -n "$APART" | cut -f 1 -d '|' | cut -f 3 -d '/'`"
  ASIZE="`echo -n "$APART" | cut -f 3 -d '|'`"
  AFS="`echo -n "$APART" | cut -f 2 -d '|'`"
  AFREE=`df -m | grep "/dev/${ATAG} " | tr -s " " | cut -f 4 -d " "`
  if [ ! $AFREE ];then
   mount -t $AFS /dev/$ATAG /mnt/data > /dev/null 2>&1
   #need to put in a check that it is not mounted ro. the
   #mount script will fallback to ro for ntfs if rw mnt fails...
   RETMNTVAL=$?
   if [ $RETMNTVAL -eq 0 ];then
    if [ "`mount | grep '(rw' | grep '/mnt/data'`" = "" ];then
     umount /mnt/data
     RETMNTVAL=1
    else
     #if the ntfs rw mount was forced (see /bin/mount script) it is unwise to use...
     ERRMSG1=""
     [ -s /tmp/ntfsmnterr.txt ] && ERRMSG1="`cat /tmp/ntfsmnterr.txt | grep 'Dirty volume mount'`"
     if [ "$ERRMSG1" != "" ];then
      T_ntfstitle="$(gettext 'First shutdown: NTFS warning')"
      T_WARNING="\Z1\Zb$(gettext 'WARNING:')\ZB"
      T_ntfs="$(eval_gettext "The ntfs-3g driver has determined that the NTFS filesystem in partition \${ATAG} is 'dirty'.")
$(gettext 'It will display in the next dialog box in the list of partitions to save to, but it is recommended that you do not use it.')
$(gettext "Instead, you should first run Microsoft Windows -- most often this problem is due to Windows not being shut down properly the last time it was used, leaving the filesystem in a 'dirty' state.")"
      T_continue="$(gettext 'Click button to continue...')"
      ${DIALOGEXE} ${BACKGROUNDPINK} ${TITLEPARAM} "$T_ntfstitle" --colors --msgbox "${T_WARNING}\n${T_ntfs}\Zn\n\n${T_continue}" 0 0
     fi
    fi
   fi
   [ -f /tmp/ntfsmnterr.txt ] && rm -f /tmp/ntfsmnterr.txt
   if [ $RETMNTVAL -eq 0 ];then
    if [ "$ATAG" = "fd0" ];then
     FFREE=`df -k | grep "/dev/$ATAG" | tr -s " " | cut -f 4 -d " "`
     AFREE=`dc $FFREE 1000 \/ p` #not 1024
    else
     #for ntfs cannot use /dev/$ATAG, use mnt point in grep...
     AFREE=`df -m | grep "/mnt/data" | tr -s " " | cut -f 4 -d " "`
    fi
    umount /mnt/data
   fi
  fi
  if [ $AFREE -ne 0 ];then
   if [ -z "$INSTALLED" ] && [ $AFREE -gt 512 ] && [ ! -s /tmp/shutdownconfig_deftag ];then
     case $AFS in
     ext?|reiserfs|minix|btrfs|f2fs) echo -n " --default-item ${ATAG}" > /tmp/shutdownconfig_deftag;;
     esac 
   fi
   if [ "$ATAG" = "$PDEV1" -a $AFREE -gt 256 ];then #120327
    echo -n " --default-item ${ATAG}" > /tmp/shutdownconfig_deftag
    echo "${ATAG} \"f.s.: $AFS  `gettext 'Size:'` ${ASIZE}M  `gettext 'Free:'` ${AFREE}M `gettext '*RECOMMENDED*'`\" " >> /tmp/schoices.txt
   else
    echo "${ATAG} \"`gettext 'Filesystem:'` $AFS  `gettext 'Size:'` ${ASIZE}M  `gettext 'Free:'` ${AFREE}M\" " >> /tmp/schoices.txt
   fi
  fi
 done
 kill $ppPID

 [ -s /tmp/shutdownconfig_deftag ] && DEFTAG="`cat /tmp/shutdownconfig_deftag`"
 [ -s /tmp/schoices.txt ] && SCHOICES="`cat /tmp/schoices.txt`"
 if [ "$SCHOICES" = "" ];then
  if [ $DISPLAY ];then
   /usr/lib/gtkdialog/box_splash -bg red -close box -fontsize large -timeout 10 -text "$T_nosave"
  else
   clear
   echo "$T_nosave"
   sleep 5
  fi
  return 1
 fi
 xSCHOICES="`cat /tmp/schoices.txt | tr '\n' ' '`"

 if [ `echo "$SCHOICES" | wc -l` -eq 1 ];then
  SAVEPART="`echo -n "$SCHOICES" | cut -f 1 -d ' '`" #no need for dlg.
 else
  T_partitiontitle="$(gettext 'First shutdown: choose partition')"
  T_menu="$(gettext 'Please choose a partition to create a pupsave on.')

$(gettext 'For Windows partitions(ntfs/vfat), Puppy makes a file with a Linux filesystem image in it. The size is typically 512MB - 4GB (it can be made bigger later).')
$(gettext 'On linux partitions(ext3 and etc.), Puppy makes a folder for pupsave. Unlike single file, the size is not predetermined but limited by the free space of the partition. A Linux partition is recommended, if available.')

$(gettext 'Highlight desired choice, then click OK button...')"
  echo '#!/bin/sh' > /tmp/savedlg
  echo -n "${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} \"${T_partitiontitle}\" --no-collapse --no-cancel ${DEFTAG} --menu \"${T_menu}\" 0 0 0 " >> /tmp/savedlg
  echo -n "$xSCHOICES"  >> /tmp/savedlg
  echo ' 2>/tmp/tag.txt' >> /tmp/savedlg
  chmod 755 /tmp/savedlg

  #seems some people have problem, do not select anything...
  T_notchosentitle="$(gettext 'First shutdown: Not chosen')"
  T_tryagain="$(gettext 'Try again')"
  T_yesno="$(gettext '\Zb\Z1ERROR:\Zn\ZB you did not choose any partition.')

$(eval_gettext 'Choose \Zb${T_tryagain}\ZB button to try again...')
$(eval_gettext 'Or, \Zb${T_abort}\ZB to shutdown without saving...')"

  while [ 1 ];do
   /tmp/savedlg
   SAVEPART="`cat /tmp/tag.txt | head -n 1`" #head is in case of errs in output.
   if [ "`echo -n "$SAVEPART" | grep --extended-regexp '^hd|^sd|^sc|^fd|^mmcblk|^nvme'`" = "" ];then
    ${DIALOGEXE} ${BACKGROUNDPINK} ${TITLEPARAM} "$T_notchosentitle" --colors --yes-label "$T_tryagain" --no-label "${T_abort}" --yesno "$T_yesno" 0 0
    [ ! $? -eq 0 ] && return 1 #abort.
    continue
   fi
   break
  done
 fi

 SAVEFS="`echo "$SCHOICES" | grep "^${SAVEPART} " | tr -s " " | cut -f 2 -d ':' | cut -f 2 -d " "`"
 SAVEFILE="$PSUBDIR/${DISTRO_FILE_PREFIX}save.2fs"
 [ "$SAVEPART" = "fd0" ] && SAVEFILE="/${DISTRO_FILE_PREFIX}save.2fs"
 PUPSAVE="$SAVEPART,$SAVEFS,$SAVEFILE"
 echo "$PUPSAVE" #TEST
 return 0
} #end choosepartfunc

choosesizefunc(){
 local KFREE SIZELIST NUM CHOICES FLABEL SLABEL ACHOICE KSIZE VALUES VALIDS val
 KFREE=$1 ; SIZELIST="" ; NUM=1 ; CHOICES=""
 MFREE=`expr $KFREE \/ 1024`
 FLABEL="${MFREE}MB"
 [ $KFREE -ge 1048576 ] && FLABEL="`dc $KFREE 1048576 \/ p`GB"
 VALUES='32 64 128 256 512 768 1024 1280 2048 4096'
 for val in $VALUES;do
 [ "$val" -gt "$DU_INITRD_PUP_RW" ] && VALIDS="$VALIDS $val"
 done
  #global: DEFAULT_SAVE_SIZE in MB
 [ $DEFAULT_SAVE_SIZE -gt 0 ] || DEFAULT_SAVE_SIZE=512
 local NDEFAULT=1
 for ACHOICE in $VALIDS
 do
  [ $ACHOICE -le $DEFAULT_SAVE_SIZE ] && NDEFAULT=$NUM
  KSIZE=`expr $ACHOICE \* 1024`
  SLABEL="${ACHOICE}MB"
  [ $ACHOICE -ge 1024 ] && SLABEL="`dc $ACHOICE 1024 \/ p`GB"
  if [ $KSIZE -lt $KFREE ];then
   SIZELIST="$SIZELIST$NUM $SLABEL "
   CHOICES="$CHOICES$KSIZE "
  else
   SIZELIST="$SIZELIST$NUM fill_partition(${FLABEL}) "
   CHOICES="$CHOICES$KFREE "
   break
  fi
  NUM=`expr $NUM + 1`
 done

 T_sizetitle="$(gettext 'First shutdown: size save-file')"
 T_sitemenu="$(gettext 'Please choose the size you would like for the personal save file.')
$(gettext 'Note, 512M is a good choice, or highest if that not available.')
$(gettext 'Select choice, then click OK button...')"
 ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_sizetitle" --no-collapse --no-cancel --default-item "$NDEFAULT" --menu "$T_sitemenu" 0 0 0 $SIZELIST 2>/tmp/sizetag.txt
 NUM=`cat /tmp/sizetag.txt`
 ACHOICE=`echo -n "$CHOICES" | cut -f $NUM -d ' '`
 #return $ACHOICE
 SIZEPFILE=$ACHOICE #global variable.
} # end of choosesizefunc()

choosestyle() {
 #do not allow save to entire partition if pup installed in a subdirectory...
 #xPSUBDIR="`echo -n "$PUPSFS" | cut -f 3 -d ',' | sed -e 's%/[^/]*$%%'`" #ex: sda3,ext2,/pup220/puppy.sfs will return /pup220
 [ "$SAVEPART" = "$PDEV1" ] && [ -z "$xPSUBDIR" ] && OFFER_PARTITION="y" || OFFER_PARTITION=""
 T_fstitle="$(gettext 'First shutdown: choose saving style')"
 T_fsmenu="$(gettext "You can save the session in a 'folder(directory)' because you chose a Linux partition. Unlike single file, saving in a folder is not restricted to the fixed file size but by the free space on the partition. You can save multiple profiles by different name.")
 
 $(gettext "A \Zbfolder\ZB is recommended for this case, but you still have another option if you have some reason and you want it.")"
 T_folder="$(gettext 'Save in a folder.') $(gettext '*RECOMMENDED*')"
 T_partition=$(gettext "Save to the entire partition. Only one profile.")
 T_file=$(gettext 'Single file, ext2/3/4 filesystem image in it.')
 if [ "$OFFER_PARTITION" ]; then
   ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_fstitle" --colors --no-cancel --default-item folder --menu "$T_fsmenu" 0 0 0 folder "$T_folder" partition "$T_partition" file "$T_file" 2>/tmp/rc.shutdown_pupsave_style
 else
   ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_fstitle" --colors --no-cancel --default-item folder --menu "$T_fsmenu" 0 0 0 folder "$T_folder" file "$T_file" 2>/tmp/rc.shutdown_pupsave_style
 fi
 SAVESTYLE=$(cat /tmp/rc.shutdown_pupsave_style)
 [ "$SAVESTYLE" ]
}

choosesize() {
 #we should check to see that there is enough space on the partition...
 PARTFREE=`df | grep "$SMNTPT" | tr -s " " | head -n 1 | cut -f 4 -d " "`
 [ ! $PARTFREE ] && PARTFREE=0
 [ $PARTFREE -lt 32768 ] && PARTFREE=`expr $PARTFREE - 1024` #leave some slack space.
 [ $PARTFREE -gt 32768 ] && PARTFREE=`expr $PARTFREE - 8192` #leave some slack space.
 SIZEPFILE=524288 #512M = 524288K
 [ $SIZEPFILE -gt  $PARTFREE ] && SIZEPFILE=$PARTFREE
 [ $PARTFREE -gt 32768 ] && choosesizefunc $PARTFREE #sets SIZEPFILE
 if [ "`echo -n $SAVEFILE | grep '\.[34]fs$'`" != "" ];then #ext3 f.s. needs minimum size.
  [ $SIZEPFILE -lt 5000 ] && return 1 #precaution. rerwin discovered this.
 fi
}

choosefs(){
 #choose f.s. of save-file... 100410 for now, leave out ext4, doesn't work...
 T_fstitle="$(gettext 'First shutdown: choose filesystem')"
 T_fsmenu="$(gettext 'Previously, Puppy has only used 'ext2', now there is a choice. Regarding power-failure, note that Puppy will do a f.s. check at next boot so ext2 can recover, however journalled filesystems can recover even without a f.s. check. If in doubt, choose 'ext2'. After making the choice, click OK button...')"
 T_ext2="$(gettext 'Maximum storage space, encrypted save-file must use ext2')"
 T_ext3="$(gettext 'Journalled f.s., safest if power failure etc.')"
 #120427 01micko: support ext4...
 T_ext4="$(gettext 'Journalled f.s., safest if power failure etc.')"
 if [ "`grep 'ext4$' /proc/filesystems`" != "" ];then #120428 technosaurus: simplify test. 
  ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_fstitle" --no-cancel --default-item ext4 --menu "$T_fsmenu" 0 0 0 ext2 "$T_ext2" ext3 "$T_ext3"  ext4 "$T_ext4" 2>/tmp/rc.shutdown_pupsave_fs #120425 01micko
 else
  ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_fstitle" --no-cancel --default-item ext3 --menu "$T_fsmenu" 0 0 0 ext2 "$T_ext2" ext3 "$T_ext3"  2>/tmp/rc.shutdown_pupsave_fs #110926
 fi
 SFFS="`cat /tmp/rc.shutdown_pupsave_fs`"
 [ "$SFFS" = "" ] && SFFS='ext2'
 SFEXTNUM="`echo -n "$SFFS" | cut -c 4`"
 SFEXT="${SFEXTNUM}fs" #ex: 2fs
}

choosename() {
 #customise the name of the ${DISTRO_FILE_PREFIX}save file...
 T_nametitle="$(gettext 'First shutdown: pupsave name')"
 T_nameinput="$(eval_gettext "Would you like to customise the name of the '\${DISTRO_FILE_PREFIX}save'?")

$(eval_gettext "This is optional, but it is convenient to manage multiple profiles. If you have lots of '\${DISTRO_FILE_PREFIX}save' and you want to choose the right one at startup.")
$(eval_gettext "For example, if you enter 'john' here, the file will become '\${DISTRO_FILE_PREFIX}save-john'.")

$(gettext 'Type any alpha-numeric characters you wish, then click OK button:')"
 MYUSERNAME="`${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_nametitle" --stdout --nocancel --inputbox "$T_nameinput" 0 0 ""`"
 NAMEONLY="${DISTRO_FILE_PREFIX}save${CRYPT_NAME}"
 if [ "$MYUSERNAME" != "" ];then
  MYUSERNAME="`echo -n "$MYUSERNAME" | tr ' ' '_' | tr '-' '_' | sed -e 's/[^a-zA-Z0-9_.]//g'`"
  NAMEONLY="$NAMEONLY-${MYUSERNAME}"
 fi
}

choosecrypt_new() {
 CRYPTO=""
 T_cryptotitle="$(gettext 'First shutdown: encryption')"
 T_cryptono="$(gettext 'NORMAL (no encryp.)')"
 T_cryptoheavy="$(gettext 'Encrypt with LUKS')"
 T_yesno="$(eval_gettext "Do you want to encrypt the '\${DISTRO_FILE_PREFIX}save'?")
$(eval_gettext "If the '\${DISTRO_FILE_PREFIX}save' is encrypted, then a password will have to be entered at every bootup. The reason for doing this is security, as no one else will be able to see what is inside the \${DISTRO_FILE_PREFIX}save. Encryption does slow \${DISTRO_NAME} down.")

LUKS = Linux Unified Key Setup.

$(eval_gettext "Encrypted \${DISTRO_FILE_PREFIX}save files have another advantage, they allow multiple users. Recommended if spouse and kids are going to be using the same \${DISTRO_NAME} installation.")

$(gettext 'Unless you have a good reason to use encryption, it is recommended not to, to avoid the overhead. Recommend choose \ZbNORMAL\ZB button...')"
 ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_cryptotitle" --colors --ok-label "$T_cryptono" --cancel-label "$T_cryptoheavy" --yesno "$T_yesno" 0 0 #110926
 RETVAL=$?
 if [ $RETVAL -eq 1 ];then
  T_passtitle="$(gettext 'First shutdown: password')"
  T_passtext="$(gettext 'Please choose a password.
This must be remembered and entered at every bootup.')"
  while [ 1 ];do
    if [ "$DISPLAY" ] ; then
      MYPASSWORD="$(/usr/lib/gtkdialog/box_passwd --show --default "puppyisgreat" "$T_passtitle" "$T_passtext")"
    else
      MYPASSWORD="`${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_passtitle" --screen-center --stdout --no-cancel --inputbox "$T_passtext" 0 0 "puppyisgreat"`" #110926
    fi
    [ "$MYPASSWORD" ] && break
  done
  DENSITY="z"
  CRYPTO='luks'
  CRYPT_NAME="_luks"
  SFEXT="4fs"
  SFFS="ext4"
 fi
}

choosecrypt() {
 CRYPTO=""
 T_cryptotitle="$(gettext 'First shutdown: encryption')"
 T_cryptono="$(gettext 'NORMAL (no encryp.)')"
 T_cryptoheavy="$(gettext 'Heavy encrypted')"
 T_cryptolight="$(gettext 'Light encrypted')"
 T_yesno="$(eval_gettext "Do you want to encrypt the '\${DISTRO_FILE_PREFIX}save'?")
$(eval_gettext "If the '\${DISTRO_FILE_PREFIX}save' is encrypted, then a password will have to be entered at every bootup. The reason for doing this is security, as no one else will be able to see what is inside the \${DISTRO_FILE_PREFIX}save. Encryption does slow \${DISTRO_NAME} down slightly, the 'heavy' encryption the most. Two scenarios:")
\Zb$(gettext '1.')\ZB $(eval_gettext "If the \${DISTRO_FILE_PREFIX}save file is on a Flash drive, encryption is protection in case the drive is mislaid. Heavy encryption is recommended, as \${DISTRO_NAME} minimises writes to the save file (to prolong life of the Flash drive, but this also minimises encryption slowdown).")
\Zb$(gettext '2.')\ZB $(eval_gettext "If the \${DISTRO_FILE_PREFIX}save file is on a hard drive, 'light' encryption is recommended to minimise slowdown, particularly on older PCs.")

$(eval_gettext "Encrypted \${DISTRO_FILE_PREFIX}save files have another advantage, they allow multiple users. Recommended if spouse and kids are going to be using the same \${DISTRO_NAME} installation.")

$(gettext 'Unless you have a good reason to use encryption, it is recommended not to, to avoid the overhead. Recommend choose \ZbNORMAL\ZB button...')"
 ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_cryptotitle" --colors --extra-button --ok-label "$T_cryptono" --cancel-label "$T_cryptoheavy" --extra-label "$T_cryptolight" --yesno "$T_yesno" 0 0 #110926
 RETVAL=$?
 if [ $RETVAL -eq 1 -o $RETVAL -eq 3 ];then
  T_passtitle="$(gettext 'First shutdown: password')"
  T_passtext="$(gettext 'Please choose a password.
This must be remembered and entered at every bootup.')"
  while [ 1 ];do
    if [ "$DISPLAY" ] ; then
      MYPASSWORD="$(/usr/lib/gtkdialog/box_passwd --show --default "puppyisgreat" "$T_passtitle" "$T_passtext")"
    else
      MYPASSWORD="`${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_passtitle" --screen-center --stdout --no-cancel --inputbox "$T_passtext" 0 0 "puppyisgreat"`" #110926
    fi
   [ "$MYPASSWORD" ] && break
  done
  modprobe cryptoloop
  if [ $RETVAL -eq 1 ];then
   DENSITY="a" #heavy aes encryption
   CRYPTO='-e aes'
   modprobe aes_generic 2>/dev/null #builtin my recent kernels.
   #did not explicitly load these two before, but do so in init script...
   modprobe crypto_blkcipher 2>/dev/null #builtin my recent kernels.
   modprobe cbc 2>/dev/null #110926 builtin in my 2.6.32-smp-45 kernel.
  else
   DENSITY="x" #light xor encryption.
   CRYPTO='-e 1' #'-e xor' --bug, loads xor.ko which is something else.
  fi 
  CRYPT_NAME="_crypt${DENSITY}"
  SFEXT="2fs"
  SFFS="ext2"
 fi
}

nameclash() {
 #save with different name if clash...
 [ ! -e $SMNTPT$SAVEFILE ] && return 0
 NAMEONLY=$(basename "$SAVEFILE")
 NAMEROOT=${NAMEONLY%.*}
 MNAMEONLY=$NAMEROOT
  T_clashtitle="$(gettext 'First shutdown: name clash')"
  T_save="$(gettext 'SAVE')"
  T_yesno="$(eval_gettext "There already exists '\${NAMEONLY}' on the partition you chose.")

$(eval_gettext 'To create another one, with a slightly different name (such as ${MNAMEONLY}-1.${SFEXT}), select \Zb${T_save}\ZB button...')
$(eval_gettext 'To quit without saving, select \Zb${T_no}\ZB button...')"
  ${DIALOGEXE} ${BACKGROUNDPINK} ${TITLEPARAM} "$T_clashtitle" --colors --yes-label "$T_save" --yesno "$T_yesno" 0 0
  [ ! $? -eq 0 ] && return 1
  local BLA=1 #; local SFFIX=`echo "$SAVEFILE" | tail -c 5`
  while [ -e $SMNTPT$SAVEFILE ]; do
   SAVEFILE="$PSUBDIR/${NAMEROOT}-${BLA}"
   [ "${SFEXT}" ] && SAVEFILE="$SAVEFILE.${SFEXT}"
   BLA=`expr $BLA + 1`
  done
}

enmount() {
 sPTN="/dev/${SAVEPART} "
 SMNTPT="`mount | grep "$sPTN" | head -n1 | tr -s " " | cut -f 3 -d " "`"
 #ntfs uses /dev/fuse so '/dev/$SAVEPART' no good for grep... NOTE: this fixed later versions ntfs-3g, so this line actually redundant...
 [ "$SMNTPT" = "" ] && SMNTPT="`ps -e | grep -o 'ntfs\-3g.*' | grep "$sPTN" | tr '\t' ' ' | tr -s ' ' | tr ' ' "\n" | grep '^/mnt/'`"
 if [ "$SMNTPT" = "" ];then
  mkdir /mnt/$SAVEPART 2>/dev/null
  mount -t $SAVEFS /dev/$SAVEPART /mnt/$SAVEPART
  SMNTPT="/mnt/$SAVEPART"
 fi
 return 0
}

changefolder() {
   T_choosefoldertitle="$(gettext 'First shutdown: choose folder')"
   T_inputbox="$(gettext 'Edit path. '/' means top-level of partition.
You are only allowed to save one-deep, for example: '/puppy300'.
If folder does not exist, it will be created. Spaces are not allowed.
If uncertain, just click OK button.')"
   NEWSAVEPATH="`${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_choosefoldertitle" --screen-center --stdout --no-cancel --inputbox "$T_inputbox" 0 0 "$SAVEPATH"`"
   [ "$NEWSAVEPATH" = "" ] && NEWSAVEPATH="$SAVEPATH"
   [ "`echo -n "$NEWSAVEPATH" | cut -b 1`" != "/" ] && NEWSAVEPATH="/${NEWSAVEPATH}"
   [ "$NEWSAVEPATH" != "/" ] && NEWSAVEPATH="`echo -n "$NEWSAVEPATH" | sed -e 's%/$%%'`"
   NEWSAVEPATH="`echo -n "$NEWSAVEPATH" | sed -e 's/ //g'`"
   SAVEPATH="$NEWSAVEPATH"
   SAVEPATHs="$SAVEPATH"
   [ "$SAVEPATH" != "/" ] && SAVEPATHs="${SAVEPATH}/"
   SAVEFILE="${SAVEPATHs}${NAMEONLY}"
   PUPSAVE="$SAVEPART,$SAVEFS,$SAVEFILE"
}

pupsavefunc() {
 SAVEPATH="`dirname $SAVEFILE`"
 #final sanity check...
 AAAMB=`expr $SIZEPFILE \/ 1024`
 T_sanititle="$(gettext 'First shutdown: sanity check')"
 T_saniyes="$(gettext 'YES, SAVE')"
 T_sanichange="$(gettext 'CHANGE FOLDER')"
 while [ 1 ];do
  nameclash || return 1
  SAVEPATH=$(dirname "$SAVEFILE")
  [ "$SAVEPATH" = '/' ] && SAVEPATH=''
  NAMEONLY=$(basename "$SAVEFILE")
  T_sanitext="`eval_gettext \"\Zb\Z1FINAL SANITY CHECK:\Zn\ZB
Partition you are saving to:      \Zb\\\${SAVEPART}\ZB
The filesystem of \\\${SAVEPART} partition: \Zb\\\${SAVEFS}\ZB
Name of the save file:            \Zb\\\${NAMEONLY}\ZB
Path (folder) of the save file:   \Zb\\\${SAVEPATH}\ZB
Size of save file:                \Zb\\\${SIZEPFILE}KB (\\\${AAAMB}MB)\ZB
Filesystem inside save file:      \Zb\\\${SFFS}\ZB

If they definitely look right, choose \Zb\\\${T_saniyes}\ZB button...
Looks ok, but you want to change the folder, choose \Zb\\\${T_sanichange}\ZB...
If anything looks wrong, choose \Zb\\\${T_notsave}\ZB...\"`"
  ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_sanititle" --colors --no-collapse --extra-button --ok-label "$T_saniyes"  --extra-label "$T_sanichange" --cancel-label "$T_notsave" --yesno "$T_sanitext" 0 0 #110926
  SANITYRET=$?
  [ $SANITYRET -ne 0 -a $SANITYRET -ne 3 ] && return 1
  [ $SANITYRET -eq 0 ] && break
  if [ $SANITYRET -eq 3 ];then #change folder.
    changefolder
  else
   SAVEFILE="${SAVEPATH}${NAMEONLY}"
   PUPSAVE="$SAVEPART,$SAVEFS,$SAVEFILE"
  fi
 done
 [ -f ${SMNTPT}${SAVEPATH} ] && return 1 #abort. must be a directory.
 [ ! -d ${SMNTPT}${SAVEPATH} ] && mkdir -p ${SMNTPT}${SAVEPATH}
 [ ! -d ${SMNTPT}${SAVEPATH} ] && return 1 #some kind of error, abort.

 [ "$SAVEPART" = "fd0" ] && SIZEPFILE=`expr $SIZEPFILE - 16`
 [ "$SFEXT" = "3fs" ] && JOPT='-j'
 #echo "Creating $NAMEONLY in /dev/$SAVEPART, please wait awhile..."
 T_createtitle="$(gettext 'First shutdown: creating save-file')"
 T_createsf="$(eval_gettext "Creating \${NAMEONLY} in \${SAVEPART}, please wait awhile (no need to click OK button)...")"
 altT_createsf="$(eval_gettext "Creating \${NAMEONLY} in \${SAVEPART}, please wait awhile...")"
 if [ $DISPLAY ];then
  #create nice window looking like prior ones...
  export SHUTDLG="<window decorated=\"false\">
<vbox>
<text use-markup=\"true\"><label>\"<big><b>${T_createtitle}</b></big>\"</label></text>
<text use-markup=\"true\"><label>\"<big>${altT_createsf}</big>\"</label></text>
</vbox>
</window>"
  GTK2_RC_FILES=/tmp/orange_gtkrc${$}:/root/.gtkrc-2.0 gtkdialog --center --class="splashwindow" --program=SHUTDLG & #130525 130712
  w1PID=$!
 else
  ${DIALOGEXE} ${BACKGROUNDORANGE} ${TITLEPARAM} "$T_createtitle" --colors --ok-label "OK" --msgbox "$T_createsf" 0 0 &
  w1PID=$!
 fi
 dd if=/dev/zero of=${SMNTPT}$SAVEFILE bs=1k count=$SIZEPFILE >&2
 sync
 #pupkill $w1PID
 echo "`eval_gettext \"Creating a \\\${SFFS} filesystem in \\\${NAMEONLY}...\"`"
 if [ "$CRYPTO" = "" ];then
  case $SFFS in
   ext2) mkfs.ext2 -q -m 0 -F ${SMNTPT}$SAVEFILE ;;
   ext3) mkfs.ext3 -q -m 0 -F ${SMNTPT}$SAVEFILE ;;
   ext4) mkfs.ext4 -q -m 0 -F ${SMNTPT}$SAVEFILE ;;
  esac
  #...default is f.s. auto checked every 26 mounts or 180 days. tune2fs to change.
  pupkill $w1PID #130525 moved down.
 else
  #note: loop2 is kept available for scripts to use. but, find which is free...
  echo -e "Save this log somewhere and close this window to continue...\n" >/tmp/mk2fs.log
  DEVLOOP="$(losetup-222 -f)"
  if [ "$CRYPTO" = "luks" ] ; then
    losetup -v $DEVLOOP ${SMNTPT}$SAVEFILE >>/tmp/mk2fs.log
    echo -n "$MYPASSWORD" | cryptsetup luksFormat -v $DEVLOOP - &>>/tmp/mk2fs.log
    echo -n "$MYPASSWORD" | cryptsetup luksOpen -v $DEVLOOP savefile - &>>/tmp/mk2fs.log
    FSCK_DEV=/dev/mapper/savefile
  else
    #'-p 0' means read password from stdin...
    echo "losetup-222 -v -p 0 $CRYPTO $DEVLOOP ${SMNTPT}$SAVEFILE" >>/tmp/mk2fs.log
    echo "$MYPASSWORD" | losetup-222 -v -p 0 $CRYPTO $DEVLOOP ${SMNTPT}$SAVEFILE &>>/tmp/mk2fs.log
    FSCK_DEV=$DEVLOOP
  fi
  echo "mke2fs -v -t $SFFS -m 0 -E nodiscard -F $FSCK_DEV" >>/tmp/mk2fs.log
  mke2fs -v -t $SFFS -m 0 -E nodiscard -F $FSCK_DEV &>>/tmp/mk2fs.log && \
  e2fsck -v -f -y -E discard $FSCK_DEV &>>/tmp/mk2fs.log || e2fsck -v -f -y $FSCK_DEV &>>/tmp/mk2fs.log
  if [ $? -ne 0 ] ; then
    pupkill $w1PID
    /usr/lib/gtkdialog/box_ok "$(gettext 'Error')" error "$(gettext 'Unable to create filesystem')"
    defaulttextviewer /tmp/mk2fs.log
  fi
  sync
  pupkill $w1PID #130525 moved down.
  [ "$CRYPTO" = "luks" ] && cryptsetup luksClose savefile
  losetup -d $DEVLOOP
 fi
 sync
 return 0
} #end pupsavefunc

save_directory() {
 #final sanity check...
 T_sanititle="$(gettext 'First shutdown: sanity check')"
 T_saniyes="$(gettext 'YES, SAVE')"
 T_sanichange="$(gettext 'CHANGE FOLDER')"
 while [ 1 ];do
  nameclash || return 1
  SAVEPATH=$(dirname "$SAVEFILE")
  [ "$SAVEPATH" = '/' ] && SAVEPATH=''
  NAMEONLY=$(basename "$SAVEFILE")
  T_sanitext="`eval_gettext \"\Zb\Z1FINAL SANITY CHECK:\Zn\ZB
Partition you are saving to:      \Zb\\\${SAVEPART}\ZB
The filesystem of \\\${SAVEPART} partition: \Zb\\\${SAVEFS}\ZB
Path (folder) of the pupsave:   \Zb\\\${SAVEPATH}/${NAMEONLY}\ZB

If they definitely look right, choose \Zb\\\${T_saniyes}\ZB button...
Looks ok, but you want to change the folder, choose \Zb\\\${T_sanichange}\ZB...
If anything looks wrong, choose \Zb\\\${T_notsave}\ZB...\"`"
  ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_sanititle" --colors --no-collapse --extra-button --ok-label "$T_saniyes"  --extra-label "$T_sanichange" --cancel-label "$T_notsave" --yesno "$T_sanitext" 0 0 #110926
  SANITYRET=$?
  [ $SANITYRET -ne 0 -a $SANITYRET -ne 3 ] && return 1
  [ $SANITYRET -eq 0 ] && break
  if [ $SANITYRET -eq 3 ];then #change folder.
    changefolder
  else
   SAVEFILE="${SAVEPATH}${NAMEONLY}"
   PUPSAVE="$SAVEPART,$SAVEFS,$SAVEFILE"
  fi
 done

 mkdir -p $SMNTPT$SAVEFILE 2>/dev/null
 PUPSAVEICON=/usr/local/apps/ROX-Filer/ROX/MIME/application-x-ext2-image.png
 [ -s "$PUPSAVEICON" ] && cp -f "$PUPSAVEICON"  "$SMNTPT$SAVEFILE/.DirIcon"

 PUPMODE=128
 SAVEPART=${SAVEPART}
 SAVEFS=${SAVEFS}
 PUPSAVE=${PUPSAVE}
 SAVEFILE=${SAVEFILE}
 NAMEONLY=${NAMEONLY}
 SAVEPATH=${SAVEPATH}
 MYPASSWORD=''
 SFEXT=''
 xPDEV=${PDEV1}
 xDEVFS=${DEV1FS}
 xPSUBDIR=${PSUBDIR}
 SMNTPT=${SMNTPT}
 CRYPTO=''
 expBOOTDRV=${expBOOTDRV}
} #end sace_directory

offersfscopy() {
	 #offer to copy $DISTRO_PUPPYSFS (puppy.sfs) and $DISTRO_ZDRVSFS (zdrv.sfs) etc off the cd...
 if [ "$DEV1FS" = "iso9660" -o "$DEV1FS" = "udf" ];then #test if booted off cd. 130128
  if [ ! -f ${SMNTPT}/${DISTRO_PUPPYSFS} ];then #see file DISTRO_SPECS, init
   NAMEONLY="`basename $SAVEFILE`"
   T_copytitle="$(gettext 'First shutdown: copy .sfs from CD')"
   T_copy="$(gettext 'COPY')"
   msg1="$(printf "$(gettext "The CD has '%s' and maybe other .sfs files on it. It will speed startup considerably if these are on the hard drive.")" "${DISTRO_PUPPYSFS}")"
   msg2="$(printf "$(gettext "Also, for PCs with less than 256MB of RAM, %s does not copy the %s file to RAM so the CD drive remains mounted, meaning that the drive cannot be used for other purposes.")" "${DISTRO_NAME}" "${DISTRO_PUPPYSFS}")"
   msg3="$(printf "$(gettext "However, if you reply \Zb%s\ZB here then it will be copied to the same drive as the '%ssave' file and loaded from there at startup, thus freeing the CD drive for other uses.")" "${T_copy}" "${DISTRO_FILE_PREFIX}")"
   msg4="$(printf "$(gettext "Even if you have heaps of RAM, it is still good to answer \Zb%s\ZB to get the faster startup.")" "${T_copy}")"
   msg5="$(printf "$(gettext "Note: if a CD has extra .sfs files on it, by copying them to the same drive as the '%ssave' file, they are then available to be loaded at startup, which is configurable by the BootManager (the BootManager is in the System menu)")" "${DISTRO_FILE_PREFIX}")"
   msg6="$(printf "$(gettext "If you answer \Zb%s\ZB here, please \Zb\Z1FIRST, RIGHT NOW\Zn\ZB, put the %s CD into the %s drive (the same one that the CD was in at startup), if it isn't already, THEN select the \Zb%s\ZB button...)")" "${T_copy}" "${DISTRO_NAME}" "${PDEV1}" "${T_copy}")"
   yesno="${msg1}\n${msg2}\n${msg3}\n${msg4}\n\n${msg5}\n\n${msg6}"
   ${DIALOGEXE} ${BACKGROUNDYELLOW} ${TITLEPARAM} "$T_copytitle" --colors --yes-label "$T_copy" --yesno "$yesno" 0 0
   RETVAL=$?
   clear
   if [ $RETVAL -eq 0 ];then
    #echo "Please wait, accessing CD drive..."
    T_waitcopy="$(gettext 'Please wait, copying .sfs files from CD...')"

    if [ $DISPLAY ];then
     #create nice window looking like prior ones...
     export COPYSFSDLG="<window decorated=\"false\">
     <vbox>
     <text use-markup=\"true\"><label>\"<big><b>${T_copytitle}</b></big>\"</label></text>
     <text use-markup=\"true\"><label>\"<big>${T_waitcopy}</big>\"</label></text>
     </vbox>
     </window>"
     GTK2_RC_FILES=/tmp/orange_gtkrc${$}:/root/.gtkrc-2.0 gtkdialog --center --class="splashwindow" --program=COPYSFSDLG & #130712
     cPID=$!
    else
     ${DIALOGEXE} ${BACKGROUNDORANGE} ${TITLEPARAM} "$T_copytitle" --msgbox "$T_waitcopy" 0 0 &
     cPID=$!
    fi

    APATTERN="/dev/$PDEV1 "
    CDMNTPT="`mount | grep "$APATTERN" | cut -f 3 -d ' '`"
    mkdir -p /mnt/$PDEV1
    if [ "$CDMNTPT" = "" ];then
     mount -t iso9660 /dev/$PDEV1 /mnt/$PDEV1
     CDMNTPT="/mnt/$PDEV1"
    fi
    for ONESFS in `find $CDMNTPT -maxdepth 1 -type f -name \*.sfs | grep -v ' ' | tr '\n' ' '`
    do
     BASESFS="`basename $ONESFS`"
     FILESIZEB=`stat --format=%s $ONESFS`
     FILESIZEK=`expr $FILESIZEB \/ 1024 + 2048` #2MB slack.
     BPATTERN=" $SMNTPT"'$'
     DRVFREEK=`df -k | tr -s ' ' | grep "$BPATTERN" | cut -f 4 -d ' '`
     if [ $DRVFREEK -gt $FILESIZEK ];then
      echo "`eval_gettext \"Copying \\\${BASESFS}...\"`"
      cp -f $ONESFS $SMNTPT/
      sync
     else
      T_cantcopy="`eval_gettext \"Insufficient space! Cannot copy \\\${BASESFS}\"`"
      echo "$T_cantcopy"
      [ $DISPLAY ] && /usr/lib/gtkdialog/box_ok "$(gettext 'Shutdown config')" error "$T_cantcopy"
      break
     fi
    done
    busybox umount $CDMNTPT
    pupkill $cPID
   fi
  fi
 fi
} #end offersfscopy

#================================================================

xDEVFS="$DEV1FS"
xPDEV="$PDEV1"
if [ "$PSAVEMARK" != "" -a "$PDEV1" != "" ];then #see /etc/rc.d/PUPSTATE
 devnameonly="`echo -n "$PDEV1" | sed -e 's/[0-9]*$//'`"
 SAVEPART="${devnameonly}${PSAVEMARK}" #partition that will-have ${DISTRO_FILE_PREFIX}save.
 spPATTERN='/dev/'"$SAVEPART"'|'
 SAVEFS="`probepart -m | grep "$spPATTERN" | cut -f 2 -d '|'`"
 xDEVFS="$SAVEFS"
 xPDEV="$SAVEPART"
fi

[ ! "$DEV1FS" ] && xDEVFS='xxx' #this will enable choice of create a save-file.

SAVECHOICE=255

# some word processing now...
T_canceltitle="$(gettext 'Click close-box to cancel shutdown')"
T_countdown="$(gettext 'Shutdown in TIME seconds')"
T_savetofile="$(gettext 'SAVE TO FILE')"
T_savetopart="`eval_gettext \"SAVE TO \\\${xPDEV}\"`"
T_orwait240=""
[ $TIMELIMIT -gt 0 ] && \
T_orwait240=$(printf "$(gettext '(Or, wait %s seconds to shutdown without saving anything)')" "$TIMELIMIT")

T_save="$(gettext 'SAVE')"
T_cd="$(gettext 'SAVE TO CD')"

#130221 note, pupdialog will exit with 255 if click window close-box, 254 if timeout.
# former, want to abort shutdown, latter, shutdown without saving.
xPSUBDIR="`echo -n "$PUPSFS" | cut -f 3 -d ',' | sed -e 's%/[^/]*$%%'`" #ex: sda3,vfat,/pup220/puppy.sfs will return /pup220
T_ms="`eval_gettext \"You can save the session and all of the settings and personal data created so far.

If unsure, it is recommended that you do save the session, so all your personal settings and files will be automatically loaded at next boot.\"`"
if [ $DISPLAY ];then
  T_display="`eval_gettext \"Click the \Zb\\\${T_save}\ZB button to be provided with the available save options, or click \Zb\\\${T_no}\ZB to exit immediately without saving anything.\"`" #111012 fix.
  yesno="$T_ms \n\n$T_display \n\n$T_orwait240"
  pupdialog --background '#FFFF80' --colors --title "$T_canceltitle" --backtitle "$T_title" --timeout $TIMELIMIT --countdown "$T_countdown" --no-label "$T_no" --yes-label "$T_save" --yesno "$yesno" 0 0 #120512
else
  T_display="`eval_gettext \"Select \Zb\\\${T_save}\ZB (just press ENTER key) to be provided with the available save options, or select \Zb\\\${T_no}\ZB (TAB then ENTER) to exit without saving.\"`"
  yesno="$T_ms \n\n$T_display \n\n$T_orwait240"
  dialog --colors --title "$T_title" --timeout $TIMELIMIT --no-label "$T_no" --yes-label "$T_save" --yesno "$yesno" 0 0 #120512
fi
SAVECHOICE=$?

case $SAVECHOICE in
 0)
  if choosepartfunc; then
    enmount
    case $SAVEFS in
      ext?|reiserfs|minix|btrfs|f2fs) SAVEFS_IS_LINUX="y";;
      *) SAVEFS_IS_LINUX="";;
    esac
    SAVESTYLE='file'
    DENSITY=''
    SFEXT=''
    if cryptsetup --help &>/dev/null && modprobe dm-crypt && modprobe xts ; then
      choosecrypt_new
    elif which losetup-222 2>/dev/null ; then
      choosecrypt
    fi
    [ -z "$DENSITY" ] && [ "$SAVEFS_IS_LINUX" ] && choosestyle
    if [ "$SAVESTYLE" = "file" ]; then
       [ -z "$DENSITY" ] && choosefs
       choosesize || exit	###FIXME###
    fi
    if [ "$SAVESTYLE" != "partition" ]; then
      choosename
      NAMEROOT="$NAMEONLY"
      [ "${SFEXT}" ] && NAMEONLY="$NAMEROOT.${SFEXT}"
      if [ "$PSAVEDIR" ];then
        SAVEFILE="${PSAVEDIR}${NAMEONLY}"
      else
        SAVEFILE="$PSUBDIR/$NAMEONLY"
      fi
      #nameclash || exit	###FIXME###
      PUPSAVE="$SAVEPART,$SAVEFS,$SAVEFILE"
    fi
    case "$SAVESTYLE" in
      folder) save_directory && PUPMODE=128;;
      partition) PUPMODE=32;;
      file) pupsavefunc && PUPMODE=128;;
      *) "SAVESTYLE=$SAVESTYLE" ;;
    esac
  fi
 ;;
 3)   echo     ;; #case already handled above.
 255) exit 255 ;; #wmreboot and wmpoweroff can cancel shutdown. 130221
 *)   echo "$(gettext 'Shutting down without saving...')" ;;
esac

if [ $PUPMODE -eq 128 ];then #will be saving session.
  offersfscopy
fi

#--------------------------------------------------
if [ ! -f ${SMNTPT}/pupswap.swp ] ; then
  if pupswap validate_drive ${SAVEPART} ; then
    ONLY_IF_NO_SWAP=1 pupswap set_dir ${SMNTPT}
  fi
fi
#--------------------------------------------------

#record all variables to a file...
#20140716 SFR: but first escape ' (if present) in MYPASSWORD
MYPASSWORD="`echo "$MYPASSWORD" | sed -e "s#'#'\\"'\\"'#g"`"
echo "PUPMODE=${PUPMODE}
SAVEPART='${SAVEPART}'
SAVEFS='${SAVEFS}'
SAVEFILE='${SAVEFILE}'
PUPSAVE='${SAVEPART},${SAVEFS},${SAVEFILE}'
NAMEONLY='${NAMEONLY}'
SAVEPATH='${SAVEPATH}'
MYPASSWORD='${MYPASSWORD}'
SFEXT='${SFEXT}'
xPDEV='${xPDEV}'
xDEVFS='${xDEVFS}'
xPSUBDIR='${xPSUBDIR}'
SMNTPT='${SMNTPT}'
CRYPTO='${CRYPTO}'
expBOOTDRV='${expBOOTDRV}'" > /tmp/shutdownconfig_results

# Add a savemark file if we save in a diffrent partition
# But not if defined by PSAVEPART in PUPSTATE
if [ "${PSAVEPART}" = "" -a "${SAVEPART}" != "${xPDEV}" ];then
 SAVEDISK=$(echo "${SAVEPART}" |  sed 's/[0-9]*//g')
 PDEV1DISK=$(echo "${xPDEV}" |  sed 's/[0-9]*//g')
 xSAVEMARK=$(echo "${SAVEPART}" |  sed 's/[^0-9]*//g')
 if [ "${SAVEDISK}" = "${PDEV1DISK}" ];then
  MOUNTED=$(grep "${xPDEV}" /proc/mounts)
  if [ "$MOUNTED" ]; then
   echo "${xSAVEMARK}" > /mnt/${xPDEV}${xPSUBDIR}/SAVEMARK
  else
   mkdir -p /mnt/${xPDEV} && mount /dev/${xPDEV} /mnt/${xPDEV}
   echo "${xSAVEMARK}" > /mnt/${xPDEV}${xPSUBDIR}/SAVEMARK
  fi
  umount /mnt/${xPDEV} 2>/dev/null
 fi
fi

exit 0
#the end#
